from flask import request
from flask_restx import Resource, Namespace, fields
from app.utils.response import success_response, error_response
from app.utils.auth import token_required
from app.utils.validators import validate_required_fields
from app.services.dictionary_service import DictionaryService

# 创建字典管理命名空间
dict_ns = Namespace('dictionaries', description='字典管理接口')

# 定义响应模型（避免循环导入）
success_response_model = dict_ns.model('SuccessResponse', {
    'code': fields.Integer(required=True, description='状态码', example=200),
    'message': fields.String(required=True, description='响应消息', example='操作成功'),
    'data': fields.Raw(description='响应数据')
})

error_response_model = dict_ns.model('ErrorResponse', {
    'code': fields.Integer(required=True, description='错误码', example=400),
    'message': fields.String(required=True, description='错误消息', example='请求参数错误'),
    'data': fields.Raw(description='错误详情')
})

pagination_model = dict_ns.model('PaginationData', {
    'page': fields.Integer(required=True, description='当前页码'),
    'limit': fields.Integer(required=True, description='每页数量'), 
    'total': fields.Integer(required=True, description='总数量'),
    'data': fields.List(fields.Raw, description='数据列表')
})

pagination_response_model = dict_ns.model('PaginationResponse', {
    'code': fields.Integer(required=True, description='状态码', example=200),
    'message': fields.String(required=True, description='响应消息', example='获取成功'),
    'data': fields.Nested(pagination_model, description='分页数据')
})

# 字典分类模型
dict_category_model = dict_ns.model('DictCategory', {
    'id': fields.Integer(required=True, description='分类ID'),
    'name': fields.String(required=True, description='字典名称'),
    'code': fields.String(required=True, description='字典编码'),
    'description': fields.String(description='描述'),
    'sort': fields.Integer(description='排序'),
    'status': fields.Boolean(description='状态'),
    'created_at': fields.String(description='创建时间'),
    'updated_at': fields.String(description='更新时间')
})

# 字典项模型
dict_item_model = dict_ns.model('DictItem', {
    'id': fields.Integer(required=True, description='字典项ID'),
    'name': fields.String(required=True, description='项名称'),
    'value': fields.String(required=True, description='数据值'),
    'category_id': fields.Integer(required=True, description='分类ID'),
    'description': fields.String(description='描述'),
    'sort': fields.Integer(description='排序'),
    'status': fields.Boolean(description='状态'),
    'created_at': fields.String(description='创建时间'),
    'updated_at': fields.String(description='更新时间')
})

# 请求模型
dict_category_create_model = dict_ns.model('DictCategoryCreate', {
    'name': fields.String(required=True, description='字典名称'),
    'code': fields.String(required=True, description='字典编码'),
    'description': fields.String(description='描述'),
    'sort': fields.Integer(description='排序', default=0),
    'status': fields.Boolean(description='状态', default=True)
})

dict_item_create_model = dict_ns.model('DictItemCreate', {
    'name': fields.String(required=True, description='项名称'),
    'value': fields.String(required=True, description='数据值'),
    'category_id': fields.Integer(required=True, description='分类ID'),
    'description': fields.String(description='描述'),
    'sort': fields.Integer(description='排序', default=0),
    'status': fields.Boolean(description='状态', default=True)
})


@dict_ns.route('/categories')
class DictCategoryListAPI(Resource):
    """字典分类列表接口"""
    
    @dict_ns.doc(
        description='获取字典分类列表（支持分页和搜索）',
        security='Bearer',
        params={
            'page': '页码（默认1）',
            'limit': '每页数量（默认10）',
            'name': '分类名称（模糊搜索）',
            'code': '分类编码（模糊搜索）',
            'status': '状态（true/false）'
        },
        responses={
            200: ('获取成功', pagination_response_model),
            401: ('未授权', error_response_model)
        }
    )
    @token_required
    def get(self, current_admin):
        """获取字典分类列表"""
        try:
            page = int(request.args.get('page', 1))
            limit = int(request.args.get('limit', 10))
            name = request.args.get('name', '').strip()
            code = request.args.get('code', '').strip()
            status = request.args.get('status')
            
            # 构建搜索关键词
            keyword = ''
            if name:
                keyword = name
            elif code:
                keyword = code
            
            # 获取分页数据
            result = DictionaryService.get_categories(page, limit, keyword)
            
            return success_response(result, '获取字典分类列表成功')
            
        except ValueError:
            return error_response('页码和每页数量必须是数字', 400)
        except Exception as e:
            return error_response(f'获取字典分类列表失败: {str(e)}', 500)
    
    @dict_ns.doc(
        description='创建字典分类',
        security='Bearer',
        responses={
            200: ('创建成功', success_response_model),
            400: ('创建失败', error_response_model),
            401: ('未授权', error_response_model)
        }
    )
    @dict_ns.expect(dict_category_create_model, validate=True)
    @token_required
    def post(self, current_admin):
        """创建字典分类"""
        try:
            data = request.get_json()
            
            # 验证必填字段
            is_valid, error_msg = validate_required_fields(['name', 'code'])
            if not is_valid:
                return error_response(error_msg, 400)
            
            # 创建字典分类
            category = DictionaryService.create_category(data)
            
            return success_response(category.to_dict(), '创建字典分类成功')
            
        except ValueError as e:
            return error_response(str(e), 400)
        except Exception as e:
            return error_response(f'创建字典分类失败: {str(e)}', 500)


@dict_ns.route('/categories/<int:category_id>')
class DictCategoryDetailAPI(Resource):
    """字典分类详情接口"""
    
    @dict_ns.doc(
        description='获取字典分类详情',
        security='Bearer',
        responses={
            200: ('获取成功', success_response_model),
            404: ('分类不存在', error_response_model),
            401: ('未授权', error_response_model)
        }
    )
    @token_required
    def get(self, current_admin, category_id):
        """获取字典分类详情"""
        try:
            category = DictionaryService.get_category_by_id(category_id)
            if not category:
                return error_response('字典分类不存在', 404)
            
            return success_response(category.to_dict(), '获取字典分类详情成功')
            
        except Exception as e:
            return error_response(f'获取字典分类详情失败: {str(e)}', 500)
    
    @dict_ns.doc(
        description='更新字典分类',
        security='Bearer',
        responses={
            200: ('更新成功', success_response_model),
            400: ('更新失败', error_response_model),
            404: ('分类不存在', error_response_model),
            401: ('未授权', error_response_model)
        }
    )
    @dict_ns.expect(dict_category_create_model, validate=True)
    @token_required
    def put(self, current_admin, category_id):
        """更新字典分类"""
        try:
            data = request.get_json()
            
            # 更新字典分类
            category = DictionaryService.update_category(category_id, data)
            if not category:
                return error_response('字典分类不存在', 404)
            
            return success_response(category.to_dict(), '更新字典分类成功')
            
        except ValueError as e:
            return error_response(str(e), 400)
        except Exception as e:
            return error_response(f'更新字典分类失败: {str(e)}', 500)
    
    @dict_ns.doc(
        description='删除字典分类',
        security='Bearer',
        responses={
            200: ('删除成功', success_response_model),
            400: ('删除失败', error_response_model),
            404: ('分类不存在', error_response_model),
            401: ('未授权', error_response_model)
        }
    )
    @token_required
    def delete(self, current_admin, category_id):
        """删除字典分类"""
        try:
            success = DictionaryService.delete_category(category_id)
            if not success:
                return error_response('字典分类不存在或删除失败', 404)
            
            return success_response(message='删除字典分类成功')
            
        except ValueError as e:
            return error_response(str(e), 400)
        except Exception as e:
            return error_response(f'删除字典分类失败: {str(e)}', 500)


@dict_ns.route('/categories/options')
class DictCategoryOptionsAPI(Resource):
    """字典分类选项接口"""
    
    @dict_ns.doc(
        description='获取字典分类选项列表（用于下拉选择）',
        security='Bearer',
        responses={
            200: ('获取成功', success_response_model),
            401: ('未授权', error_response_model)
        }
    )
    @token_required
    def get(self, current_admin):
        """获取字典分类选项列表"""
        try:
            categories = DictionaryService.get_active_categories()
            
            return success_response(categories, '获取字典分类选项成功')
            
        except Exception as e:
            return error_response(f'获取字典分类选项失败: {str(e)}', 500)


@dict_ns.route('/items')
class DictItemListAPI(Resource):
    """字典项列表接口"""
    
    @dict_ns.doc(
        description='获取字典项列表（支持分页和搜索）',
        security='Bearer',
        params={
            'page': '页码（默认1）',
            'limit': '每页数量（默认10）',
            'category_id': '分类ID',
            'name': '项名称（模糊搜索）',
            'value': '数据值（模糊搜索）',
            'status': '状态（true/false）'
        },
        responses={
            200: ('获取成功', pagination_response_model),
            401: ('未授权', error_response_model)
        }
    )
    @token_required
    def get(self, current_admin):
        """获取字典项列表"""
        try:
            page = int(request.args.get('page', 1))
            limit = int(request.args.get('limit', 10))
            category_id = request.args.get('category_id')
            name = request.args.get('name', '').strip()
            value = request.args.get('value', '').strip()
            status = request.args.get('status')
            
            # 构建搜索关键词
            keyword = ''
            if name:
                keyword = name
            elif value:
                keyword = value
            
            # 获取分页数据
            dict_id = int(category_id) if category_id else None
            result = DictionaryService.get_items(dict_id, page, limit, keyword)
            
            return success_response(result, '获取字典项列表成功')
            
        except ValueError:
            return error_response('页码、每页数量和分类ID必须是数字', 400)
        except Exception as e:
            return error_response(f'获取字典项列表失败: {str(e)}', 500)
    
    @dict_ns.doc(
        description='创建字典项',
        security='Bearer',
        responses={
            200: ('创建成功', success_response_model),
            400: ('创建失败', error_response_model),
            401: ('未授权', error_response_model)
        }
    )
    @dict_ns.expect(dict_item_create_model, validate=True)
    @token_required
    def post(self, current_admin):
        """创建字典项"""
        try:
            data = request.get_json()
            
            # 验证必填字段
            is_valid, error_msg = validate_required_fields(['name', 'value', 'category_id'])
            if not is_valid:
                return error_response(error_msg, 400)
            
            # 创建字典项
            item = DictionaryService.create_item(data)
            
            return success_response(item.to_dict(), '创建字典项成功')
            
        except ValueError as e:
            return error_response(str(e), 400)
        except Exception as e:
            return error_response(f'创建字典项失败: {str(e)}', 500)


@dict_ns.route('/items/<int:item_id>')
class DictItemDetailAPI(Resource):
    """字典项详情接口"""
    
    @dict_ns.doc(
        description='获取字典项详情',
        security='Bearer',
        responses={
            200: ('获取成功', success_response_model),
            404: ('字典项不存在', error_response_model),
            401: ('未授权', error_response_model)
        }
    )
    @token_required
    def get(self, current_admin, item_id):
        """获取字典项详情"""
        try:
            item = DictionaryService.get_item_by_id(item_id)
            if not item:
                return error_response('字典项不存在', 404)
            
            return success_response(item.to_dict(), '获取字典项详情成功')
            
        except Exception as e:
            return error_response(f'获取字典项详情失败: {str(e)}', 500)
    
    @dict_ns.doc(
        description='更新字典项',
        security='Bearer',
        responses={
            200: ('更新成功', success_response_model),
            400: ('更新失败', error_response_model),
            404: ('字典项不存在', error_response_model),
            401: ('未授权', error_response_model)
        }
    )
    @dict_ns.expect(dict_item_create_model, validate=True)
    @token_required
    def put(self, current_admin, item_id):
        """更新字典项"""
        try:
            data = request.get_json()
            
            # 更新字典项
            item = DictionaryService.update_item(item_id, data)
            if not item:
                return error_response('字典项不存在', 404)
            
            return success_response(item.to_dict(), '更新字典项成功')
            
        except ValueError as e:
            return error_response(str(e), 400)
        except Exception as e:
            return error_response(f'更新字典项失败: {str(e)}', 500)
    
    @dict_ns.doc(
        description='删除字典项',
        security='Bearer',
        responses={
            200: ('删除成功', success_response_model),
            404: ('字典项不存在', error_response_model),
            401: ('未授权', error_response_model)
        }
    )
    @token_required
    def delete(self, current_admin, item_id):
        """删除字典项"""
        try:
            success = DictionaryService.delete_item(item_id)
            if not success:
                return error_response('字典项不存在或删除失败', 404)
            
            return success_response(message='删除字典项成功')
            
        except Exception as e:
            return error_response(f'删除字典项失败: {str(e)}', 500)


@dict_ns.route('/items/by-code/<string:code>')
class DictItemsByCodeAPI(Resource):
    """根据编码获取字典项接口"""
    
    @dict_ns.doc(
        description='根据字典编码获取对应的字典项列表',
        security='Bearer',
        responses={
            200: ('获取成功', success_response_model),
            404: ('字典分类不存在', error_response_model),
            401: ('未授权', error_response_model)
        }
    )
    @token_required
    def get(self, current_admin, code):
        """根据字典编码获取字典项列表"""
        try:
            items = DictionaryService.get_items_by_code(code)
            if items is None:
                return error_response('字典分类不存在', 404)
            
            return success_response(items, f'获取字典项列表成功')
            
        except Exception as e:
            return error_response(f'获取字典项列表失败: {str(e)}', 500) 